package jblip.gui.components;

import java.awt.BorderLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.File;
import java.lang.reflect.InvocationTargetException;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
import javax.swing.SwingUtilities;

import jblip.BlipClient;
import jblip.gui.JBlip;
import jblip.gui.data.channels.UpdatesDataChannel;
import jblip.gui.data.channels.UserDataChannel;

public class InputPanel extends JPanel implements ActionListener {
  private static final long serialVersionUID = 1L;

  private static final ImageIcon ICON_MSG_LOCKED;

  private static final ImageIcon ICON_MSG_LOCKABLE;

  private static final ImageIcon ICON_MSG_NOTLOCKABLE;

  private static final ImageIcon ICON_PHOTO_ATTACHED;

  private static final ImageIcon ICON_PHOTO_NONE;

  private static final Insets ICON_INSETS = new Insets(1, 1, 1, 1);

  static {
    ICON_MSG_LOCKABLE =
        new ImageIcon(InputPanel.class
            .getResource("/jblip/gui/resources/icon-publicmsg.png"));
    ICON_MSG_LOCKED =
        new ImageIcon(InputPanel.class
            .getResource("/jblip/gui/resources/icon-privatemsg.png"));

    ICON_MSG_NOTLOCKABLE =
        new ImageIcon(InputPanel.class
            .getResource("/jblip/gui/resources/icon-notlockablemsg.png"));

    ICON_PHOTO_ATTACHED =
        new ImageIcon(InputPanel.class
            .getResource("/jblip/gui/resources/icon-attachment.png"));

    ICON_PHOTO_NONE =
        new ImageIcon(InputPanel.class
            .getResource("/jblip/gui/resources/icon-noattachment.png"));
  }

  private final JTextField text;

  private final JToggleButton button_lock;

  private final JToggleButton button_attach;

  private final JButton button_send;

  private JLabel text_label;

  private UpdatesDataChannel current_channel;

  private File attachment_directory;

  private File attached_picture;

  public InputPanel() {
    current_channel = null;
    text_label = new JLabel("");
    text = new JTextField();
    text.addKeyListener(new KeyAdapter() {
      @Override
      public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
          sendMessage();
        }
      }
    });

    button_lock = new JToggleButton(ICON_MSG_LOCKABLE);
    button_lock.setContentAreaFilled(false);
    button_lock.setMargin(ICON_INSETS);
    button_lock.setDisabledIcon(ICON_MSG_NOTLOCKABLE);
    button_lock.setSelectedIcon(ICON_MSG_LOCKED);
    button_lock.addActionListener(this);

    button_attach = new JToggleButton(ICON_PHOTO_NONE);
    button_attach.setContentAreaFilled(false);
    button_attach.setMargin(ICON_INSETS);
    button_attach.setSelectedIcon(ICON_PHOTO_ATTACHED);
    button_attach.addActionListener(this);

    button_send = new JButton("Wyślij");
    button_send.setDefaultCapable(true);
    button_send.setContentAreaFilled(false);
    button_send.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(final ActionEvent e) {
        sendMessage();
      }
    });

    final JPanel text_panel = new JPanel();
    text_panel.setLayout(new BoxLayout(text_panel, BoxLayout.LINE_AXIS));
    text_panel.add(Box.createHorizontalStrut(5));
    text_panel.add(text_label);
    text_panel.add(Box.createHorizontalStrut(5));
    text_panel.add(text);
    text_panel.add(Box.createHorizontalStrut(5));

    final JPanel button_panel = new JPanel();
    button_panel.setLayout(new BoxLayout(button_panel, BoxLayout.LINE_AXIS));

    button_panel.add(Box.createHorizontalStrut(5));
    button_panel.add(button_lock);
    button_panel.add(Box.createHorizontalStrut(5));
    button_panel.add(button_attach);
    button_panel.add(Box.createHorizontalGlue());
    button_panel.add(button_send);
    button_panel.add(Box.createHorizontalStrut(5));

    this.setLayout(new BorderLayout(5, 5));
    this.add(text_panel, BorderLayout.CENTER);
    this.add(button_panel, BorderLayout.PAGE_END);
  }

  void setChannel(final UpdatesDataChannel channel) {
    if (channel.equals(current_channel)) {
      return;
    }

    current_channel = channel;

    if (channel instanceof UserDataChannel) {
      button_lock.setEnabled(true);
      button_lock.setSelected(false);
    } else {
      button_lock.setEnabled(false);
    }

    updateTextLabel();
  }

  private void sendMessage() {
    text.setEnabled(false);
    button_send.setEnabled(false);
    System.err.println("Sending message: " + text.getText());
    final WaitFrame wait_frame = new WaitFrame("Post", "Wysyłanie wiadomości");

    String rcpt = null;
    final boolean priv = button_lock.isSelected();

    if (current_channel instanceof UserDataChannel) {
      rcpt = ((UserDataChannel) current_channel).getUserName();
    }

    wait_frame.runTask(sendMessageThread(
        text.getText(), rcpt, priv, attached_picture));
  }

  private Thread sendMessageThread(final String body, final String recipient,
      final boolean is_private, final File picture) {
    return new Thread(new Runnable() {
      private void reset(final boolean clear) {
        try {
          SwingUtilities.invokeAndWait(new Runnable() {
            @Override
            public void run() {
              if (clear) {
                text.setText("");
                button_attach.setSelected(false);
              }
              text.setEnabled(true);
              button_send.setEnabled(true);
              text.grabFocus();
            }
          });
        } catch (InterruptedException e) {
          e.printStackTrace();
        } catch (InvocationTargetException e) {
          e.printStackTrace();
        }
      }

      @Override
      public void run() {
        final BlipClient client = JBlip.instance().getBlipClient();

        if (recipient == null) {
          if (picture == null) {
            client.postMessage(body);
          } else {
            client.postMessage(body, picture);
          }
        } else {
          if (picture == null && is_private) {
            client.postPrivateMessage(body, recipient);
          } else if (picture == null && !is_private) {
            client.postMessage(body, recipient);
          } else if (picture != null && is_private) {
            client.postPrivateMessage(body, recipient, picture);
          } else {
            client.postMessage(body, recipient, picture);
          }
        }

        if (client.getLastError() == null) {
          reset(true);
        } else {
          JOptionPane.showMessageDialog(
              InputPanel.this, "Błąd przy wysyłaniu wiadomości", "Błąd",
              JOptionPane.ERROR_MESSAGE);
          System.err.println(client.getLastError().toString());
          reset(false);
        }
      }
    });
  }

  private void updateTextLabel() {
    System.err.println("Setting lock state to: " + button_lock.isSelected());
    if (current_channel instanceof UserDataChannel) {
      final String uname = ((UserDataChannel) current_channel).getUserName();
      if (button_lock.isSelected()) {
        text_label.setText(">>" + uname + ":");
      } else {
        text_label.setText(">" + uname + ":");
      }
    } else {
      text_label.setText("");
    }
    this.invalidate();
    this.repaint();
  }

  @Override
  public void actionPerformed(final ActionEvent e) {
    if (e.getSource().equals(button_attach)) {
      if (attachment_directory == null) {
        attachment_directory = new File(System.getProperty("user.home"));
      }
      if (button_attach.isSelected()) {
        final JFileChooser picture_chooser =
            new JFileChooser(attachment_directory);
        picture_chooser.setDialogTitle("Wybierz plik do wysłania");

        final int selection = picture_chooser.showOpenDialog(this);

        if (selection == JFileChooser.APPROVE_OPTION) {
          attached_picture = picture_chooser.getSelectedFile();
          attachment_directory = picture_chooser.getCurrentDirectory();
        } else {
          attached_picture = null;
          button_attach.setSelected(false);
        }
      } else {
        attached_picture = null;
      }
    } else if (e.getSource().equals(button_lock)) {
      updateTextLabel();
    }
  }
}
